import React from 'react';
import {render} from 'react-dom';
import cx from 'classnames';
import Icon from './icons/index';
import Button from './Button';

import './styles/Modal.less';
const T = React.PropTypes;

class Modal extends React.Component {
  static propTypes = {
    visible: React.PropTypes.bool,
    onClose: React.PropTypes.func,
    style: T.object,
    children: T.oneOfType([
      T.array, T.object
    ])
  };

  constructor(props) {
    super(props);
    this.state = {
      className: "comp-modal"
    };
  }

  componentDidMount() {
    setTimeout(() =>
      this.setState({ className: cx('comp-modal', { 'comp-modal-visible': this.props.visible }) }), 100);

  }

  componentWillReceiveProps(nextProps) {
    this.setState({ className: cx('comp-modal', { 'comp-modal-visible': nextProps.visible }) });
  }

  render() {
    let {style, children} = this.props;
    return (
      <div className={this.state.className} onClick={this.props.onClose}>
        <div className="comp-modal-content" style={style} onClick={(e) => e.stopPropagation() }>
          <Icon type="close-round" className="comp-modal-close" onClick={this.props.onClose}/>
          {children}
        </div>
      </div>
    );
  }
}

class OutBee extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      messages: [],
      modals: []
    };
  }

  addMessage(message, messageId, timeout) {
    this.setState({ messages: this.state.messages.concat({ message, messageId, timeout }) });
    setTimeout(()=>this.removeMessage(messageId), timeout);
  }

  removeMessage(messageId) {
    this.setState({ messages: this.state.messages.filter((m) => m.messageId != messageId) });
  }

  addModal(modalKey, content, onClose, options = {}) {
    this.state.modals.push({ modalKey, content, options, onClose, visible: true });
    this.setState({ modals: this.state.modals });
  }

  removeModal(k) {
    this.setState({ modals: this.state.modals.map((m) => m.modalKey == k ? Object.assign(m, { visible: false }) : m) }, () => {
      setTimeout(() => this.setState({ modals: this.state.modals.filter((m) => m.modalKey != k) }), 100);
    });
  }

  render() {
    return (
      <div>
        {this.state.messages.map(({message, messageId}) => (
          <div className="outBee-message" key={messageId}>
            <div className="outBee-message-wrapper">
              <Icon type="close-round" className="outBee-message-close" onClick={()=>this.removeMessage(messageId)}/>
              {message}
            </div>
          </div>
        )) }
        {this.state.modals.map(({visible, onClose, modalKey, content, options}) => {
          let {style} = options;
          return <Modal key={modalKey} {...{ style, onClose, visible }}>{content}</Modal>
        }) }
      </div>
    )
  }
}
let div = document.createElement('div');
document.body.appendChild(div);
let outBeeApp = render(<OutBee/>, div);

const message = {
  info(message, timeout = 3000) {
    let messageId = Date.now();
    outBeeApp.addMessage(message, messageId, timeout);
  },
  success(message, timeout = 3000) {
    let messageId = Date.now();
    outBeeApp.addMessage(<span style={{color: '#66cc33'}}>{message}</span>, messageId, timeout);
  },
  warn(message, timeout = 3000) {
    let messageId = Date.now();
    outBeeApp.addMessage(<span style={{color: '#ffff66'}}>{message}</span>, messageId, timeout);
  },
  error(message, timeout = 3000) {
    let messageId = Date.now();
    outBeeApp.addMessage(<span style={{color: '#ff6633'}}>{message}</span>, messageId, timeout);
  }
};
function confirm(message, ok, cancel) {
  let close = show((
    <div>
      <h3>{message}</h3>
      <Button onClick={() => ok(close) }>确定</Button>
      <Button onClick={() => _.isFunction(cancel) ? cancel(close) : close() } style={{ float: 'right' }}>取消</Button>
    </div>
  ), () => cancel ? cancel(close) : close());
  return close;
}
function show(content) {
  let modalKey = Date.now();
  let close = function () {
    outBeeApp.removeModal(modalKey);
  };
  outBeeApp.addModal(modalKey, content, close);
  return close;
}
Modal.message = message;
Modal.confirm = confirm;
Modal.show = show;
export default Modal;